import React, { createContext, useContext, useState, useEffect } from "react";
import { RouteConfig } from "./types";
import { routes as baseRoutes } from "./config";

interface DynamicRouteContextType {
  // 所有路由配置
  routes: RouteConfig[];
  // 添加路由
  addRoute: (route: RouteConfig, parentPath?: string) => boolean;
  // 移除路由
  removeRoute: (path: string) => boolean;
  // 更新路由
  updateRoute: (path: string, updatedRoute: Partial<RouteConfig>) => boolean;
  // 重置路由
  resetRoutes: () => void;
}

const DynamicRouteContext = createContext<DynamicRouteContextType | undefined>(
  undefined
);

export const useDynamicRoutes = () => {
  const context = useContext(DynamicRouteContext);
  if (!context) {
    throw new Error(
      "useDynamicRoutes must be used within a DynamicRouteProvider"
    );
  }
  return context;
};

interface DynamicRouteProviderProps {
  children: React.ReactNode;
  initialRoutes?: RouteConfig[];
}

export const DynamicRouteProvider: React.FC<DynamicRouteProviderProps> = ({
  children,
  initialRoutes = baseRoutes,
}) => {
  const [routes, setRoutes] = useState<RouteConfig[]>(initialRoutes);

  // 添加路由
  const addRoute = (newRoute: RouteConfig, parentPath?: string): boolean => {
    // 如果没有指定父路径，直接添加到顶级路由
    if (!parentPath) {
      setRoutes((prevRoutes) => [...prevRoutes, newRoute]);
      return true;
    }

    // 查找父路由并添加子路由
    const updatedRoutes = [...routes];
    let success = false;

    const addToParent = (
      routes: RouteConfig[],
      parentPath: string
    ): boolean => {
      for (let i = 0; i < routes.length; i++) {
        const route = routes[i];
        if (route.path === parentPath) {
          // 找到父路由，添加子路由
          if (!route.children) {
            route.children = [];
          }
          route.children.push(newRoute);
          return true;
        }

        // 递归检查子路由
        if (route.children) {
          if (addToParent(route.children, parentPath)) {
            return true;
          }
        }
      }

      return false;
    };

    success = addToParent(updatedRoutes, parentPath);

    if (success) {
      setRoutes(updatedRoutes);
    }

    return success;
  };

  // 移除路由
  const removeRoute = (path: string): boolean => {
    if (!path) return false;

    const updatedRoutes = [...routes];
    let success = false;

    const removeFromRoutes = (routes: RouteConfig[], path: string): boolean => {
      for (let i = 0; i < routes.length; i++) {
        const route = routes[i];

        // 检查当前路由
        if (route.path === path) {
          routes.splice(i, 1);
          return true;
        }

        // 递归检查子路由
        if (route.children) {
          if (removeFromRoutes(route.children, path)) {
            return true;
          }
        }
      }

      return false;
    };

    success = removeFromRoutes(updatedRoutes, path);

    if (success) {
      setRoutes(updatedRoutes);
    }

    return success;
  };

  // 更新路由
  const updateRoute = (
    path: string,
    updatedRoute: Partial<RouteConfig>
  ): boolean => {
    if (!path) return false;

    const updatedRoutes = [...routes];
    let success = false;

    const updateRouteInList = (
      routes: RouteConfig[],
      path: string
    ): boolean => {
      for (let i = 0; i < routes.length; i++) {
        const route = routes[i];

        // 检查当前路由
        if (route.path === path) {
          routes[i] = { ...route, ...updatedRoute };
          return true;
        }

        // 递归检查子路由
        if (route.children) {
          if (updateRouteInList(route.children, path)) {
            return true;
          }
        }
      }

      return false;
    };

    success = updateRouteInList(updatedRoutes, path);

    if (success) {
      setRoutes(updatedRoutes);
    }

    return success;
  };

  // 重置路由
  const resetRoutes = () => {
    setRoutes(initialRoutes);
  };

  // 当初始路由变化时更新
  useEffect(() => {
    setRoutes(initialRoutes);
  }, [initialRoutes]);

  const value = {
    routes,
    addRoute,
    removeRoute,
    updateRoute,
    resetRoutes,
  };

  return (
    <DynamicRouteContext.Provider value={value}>
      {children}
    </DynamicRouteContext.Provider>
  );
};

export default DynamicRouteProvider;
